package com.ccrfid.rmc6.service.business.patrol;

import com.ccrfid.rmc6.appconfig.exception.pojo.AppException;
import com.ccrfid.rmc6.appconfig.exception.pojo.CustomErrors;
import com.ccrfid.rmc6.entity.business.patrol.PatrolGroupEntity;
import com.ccrfid.rmc6.entity.business.patrol.PatrolGroupPersonnelEntity;
import com.ccrfid.rmc6.entity.business.patrol.PatrolLocationEntity;
import com.ccrfid.rmc6.entity.business.patrol.PatrolTimeRangeEntity;
import com.ccrfid.rmc6.entity.poi.PoiLocationEntity;
import com.ccrfid.rmc6.pojo.Constants;
import com.ccrfid.rmc6.pojo.dto.patrol.PatrolGroupDto;
import com.ccrfid.rmc6.pojo.dto.patrol.PatrolPersonnelDto;
import com.ccrfid.rmc6.repository.business.patrol.*;
import com.ccrfid.rmc6.repository.personnel.PersonnelRepository;
import com.ccrfid.rmc6.repository.poi.PoiLocationRepository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.transaction.Transactional;
import javax.ws.rs.core.Response;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

@Service
@Transactional
public class PatrolConfigServiceImpl implements PatrolConfigService {
    private static final Logger logger = LoggerFactory.getLogger(PatrolConfigServiceImpl.class);
    @Autowired
    private PatrolGroupRepository patrolGroupRepository;
    @Autowired
    private PatrolGroupPersonnelRepository patrolGroupPersonnelRepository;
    @Autowired
    private PersonnelRepository personnelRepository;
    @Autowired
    private PatrolLocationRepository patrolLocationRepository;
    @Autowired
    private PoiLocationRepository poiLocationRepository;
    @Autowired
    private PatrolScheduleRepository patrolScheduleRepository;
    @Autowired
    private PatrolTimeRangeRepository patrolTimeRangeRepository;

    @Override
    public List<PatrolTimeRangeEntity> getPatrolTimeRanges() {
        return patrolTimeRangeRepository.getAllByTimeRangeType(1);
    }

    @Override
    public List<PatrolGroupDto> getPatrolGroupInfoList() {
        List<PatrolGroupDto> list = new ArrayList<>();
        List<PatrolGroupEntity> patrolGroupEntities = patrolGroupRepository.getAllBy();
        for (PatrolGroupEntity patrolGroup : patrolGroupEntities) {
            PatrolGroupDto dto = new PatrolGroupDto();
            dto.setPatrolGroup(patrolGroup);
            dto.setPersonnelList(patrolGroupPersonnelRepository.getAllByGroupId(patrolGroup.getId()));
            list.add(dto);
        }
        return list;
    }

    @Override
    public PatrolGroupDto getPatrolGroupInfo(Long groupId) {
        PatrolGroupEntity patrolGroup = patrolGroupRepository.getById(groupId);
        if (patrolGroup != null) {
            PatrolGroupDto dto = new PatrolGroupDto();
            dto.setPatrolGroup(patrolGroup);
            dto.setPersonnelList(patrolGroupPersonnelRepository.getAllByGroupId(groupId));
            return dto;
        }
        return null;
    }

    @Override
    public List<PatrolPersonnelDto> getPatrolPersonnelList() {
        List<Long> personnelIdList = getPersonnelIdList();
        List<PatrolPersonnelDto> list = new ArrayList<>();
        //民警
        PatrolPersonnelDto policeDto = new PatrolPersonnelDto();
        policeDto.setPersonnelType(Constants.PERSONNEL_TYPE.POLICE.id);
        policeDto.setPersonnelTypeName(Constants.PERSONNEL_TYPE.POLICE.name);
        if (personnelIdList.size() > 0) {
            policeDto.setPersonnelList(personnelRepository.getAllByEnabledAndPersonnelTypeAndIdNotIn(1,
                    Constants.PERSONNEL_TYPE.POLICE.id, personnelIdList));
        } else {
            policeDto.setPersonnelList(personnelRepository.getAllByEnabledAndPersonnelType(1, Constants.PERSONNEL_TYPE.POLICE.id));
        }
        list.add(policeDto);
        //文职人员
        PatrolPersonnelDto wenzhiDto = new PatrolPersonnelDto();
        wenzhiDto.setPersonnelType(Constants.PERSONNEL_TYPE.WEN_ZHI.id);
        wenzhiDto.setPersonnelTypeName(Constants.PERSONNEL_TYPE.WEN_ZHI.name);
        if (personnelIdList.size() > 0) {
            wenzhiDto.setPersonnelList(personnelRepository.getAllByEnabledAndPersonnelTypeAndIdNotIn(1,
                    Constants.PERSONNEL_TYPE.WEN_ZHI.id, personnelIdList));
        } else {
            wenzhiDto.setPersonnelList(personnelRepository.getAllByEnabledAndPersonnelType(1, Constants.PERSONNEL_TYPE.WEN_ZHI.id));
        }
        list.add(wenzhiDto);

        return list;
    }

    private List<Long> getPersonnelIdList() {
        List<PatrolGroupPersonnelEntity> patrolPersonnelList = patrolGroupPersonnelRepository.getAllBy();
        List<Long> personnelIdList = new ArrayList<>();
        for (PatrolGroupPersonnelEntity patrolPersonnel : patrolPersonnelList) {
            personnelIdList.add(patrolPersonnel.getPersonnelId());
        }
        return personnelIdList;
    }

    @Override
    public PatrolGroupDto createPatrolGroupInfo(PatrolGroupDto patrolGroupDto) throws AppException {
        PatrolGroupEntity patrolGroupEntity = patrolGroupRepository.save(patrolGroupDto.getPatrolGroup());
        List<PatrolGroupPersonnelEntity> personnelList = patrolGroupDto.getPersonnelList();
        if (patrolGroupEntity != null && personnelList != null) {
            for (PatrolGroupPersonnelEntity patrolGroupPersonnelEntity : personnelList) {
                patrolGroupPersonnelEntity.setGroupId(patrolGroupEntity.getId());
                patrolGroupPersonnelRepository.save(patrolGroupPersonnelEntity);
            }
        }
        return patrolGroupDto;
    }

    @Override
    public PatrolGroupDto updatePatrolGroupInfo(Long groupId, PatrolGroupDto patrolGroupDto) throws AppException {
        PatrolGroupEntity patrolGroupEntity = patrolGroupDto.getPatrolGroup();
        if (!groupId.equals(patrolGroupEntity.getId())) {
            throw new AppException(Response.Status.BAD_REQUEST.getStatusCode(),
                    CustomErrors.different_args.getCode(), CustomErrors.different_args.getReason(), "");
        }
        //保存组名称
        patrolGroupRepository.save(patrolGroupEntity);
        //删除老人员数据
        patrolGroupPersonnelRepository.deleteAllByGroupId(groupId);
        //增加新人员数据
        List<PatrolGroupPersonnelEntity> newPersonnelList = patrolGroupDto.getPersonnelList();
        for (PatrolGroupPersonnelEntity entity : newPersonnelList) {
            entity.setGroupId(groupId);
            patrolGroupPersonnelRepository.save(entity);
        }
        return patrolGroupDto;
    }

    @Override
    public Boolean deletePatrolGroupInfo(Long groupId) throws AppException {
        if (!patrolGroupRepository.existsById(groupId)) {
            throw new AppException(Response.Status.BAD_REQUEST.getStatusCode(),
                    CustomErrors.resource_not_found.getCode(), CustomErrors.resource_not_found.getReason(), "");
        } else {
            //删除相关patrol_schedule
            patrolScheduleRepository.deleteAllByGroupId(groupId);
            //删除组相关人员
            patrolGroupPersonnelRepository.deleteAllByGroupId(groupId);
            //删除patrol_group
            patrolGroupRepository.deleteById(groupId);
        }
        return true;
    }

    @Override
    public List<PatrolLocationEntity> getPatrolLocationList() {
        return patrolLocationRepository.getAllBy();
    }

    @Override
    public List<PoiLocationEntity> getFreeLocations() {
        Set<Long> locationIdSet = getLocationIdSet();
        if (locationIdSet.size() > 0) {
            return poiLocationRepository.getAllByLocationTypeAndIdNotIn(Constants.LOCATION_TYPE.PATROL.id, locationIdSet);
        } else {
            return poiLocationRepository.getAllByLocationType(Constants.LOCATION_TYPE.PATROL.id);
        }
    }

    private Set<Long> getLocationIdSet() {
        Set<Long> set = new HashSet<>();
        List<PatrolLocationEntity> list = patrolLocationRepository.getAllBy();
        for (PatrolLocationEntity locationEntity : list) {
            set.add(locationEntity.getLocationId());
        }
        return set;
    }

    @Override
    public PatrolLocationEntity getPatrolLocation(Long locationId) {
        return patrolLocationRepository.getByLocationId(locationId);
    }

    @Override
    public PatrolLocationEntity createPatrolLocation(PatrolLocationEntity patrolLocation) throws AppException {
        return patrolLocationRepository.save(patrolLocation);
    }

    @Override
    public PatrolLocationEntity updatePatrolLocation(Long locationId, PatrolLocationEntity patrolLocation) throws AppException {
        if (!locationId.equals(patrolLocation.getLocationId())) {
            throw new AppException(Response.Status.BAD_REQUEST.getStatusCode(),
                    CustomErrors.different_args.getCode(), CustomErrors.different_args.getReason(), "");
        }
        return patrolLocationRepository.save(patrolLocation);
    }

    @Override
    public Boolean deletePatrolLocation(Long locationId) throws AppException {
        PatrolLocationEntity patrolLocationEntity = patrolLocationRepository.getByLocationId(locationId);
        if (patrolLocationEntity == null) {
            throw new AppException(Response.Status.BAD_REQUEST.getStatusCode(),
                    CustomErrors.resource_not_found.getCode(), CustomErrors.resource_not_found.getReason(), "");
        } else {
            patrolLocationRepository.delete(patrolLocationEntity);
        }
        return true;
    }
}
